package handling;

import constants.ServerConstants;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Properties;
import server.ServerProperties;
import tools.EncodingDetect;
import tools.FileoutputUtil;

public enum SendPacketOpcode implements WritableIntValueHolder {

    PING,
    LOGIN_STATUS,
    AUTO_LOGIN_STATUS,
    SERVERLIST,
    CHARLIST,
    SERVER_IP,
    CHAR_NAME_RESPONSE,
    ADD_NEW_CHAR_ENTRY,
    DELETE_CHAR_RESPONSE,
    CHANGE_CHANNEL,
    CS_USE,
    EVENT_CHECK,
    WORK_RESPONSE,
    LICENSE_RESULT,
    CHOOSE_GENDER,
    GENDER_SET,
    REGISTER_INFO,
    CHECK_ACCOUNT_INFO,
    REGISTER_ACCOUNT,
    UNK0008,
    SHOW_CHAR_CARDS,
    SHOW_ACC_CASH,
    WZ_CHECK,
    SERVERSTATUS,
    CHANNEL_SELECTED,
    RSA_KEY,
    ENABLE_RECOMMENDED,
    SEND_RECOMMENDED,
    LOGIN_AUTH,
    EJECT_WEB,
    SECONDPW_ERROR,
    LOGIN_SECOND,
    PIN_OPERATION,
    ALL_CHARLIST,
    MODIFY_INVENTORY_ITEM,
    UPDATE_INVENTORY_SLOT,
    UPDATE_STATS,
    GIVE_BUFF,
    CANCEL_BUFF,
    TEMP_STATS,
    TEMP_STATS_RESET,
    UPDATE_SKILLS,
    UPDATE_SKILL_TICK,
    SKILL_MEMORY,
    FAME_RESPONSE,
    SHOW_STATUS_INFO,
    SHOW_NOTES,
    TROCK_LOCATIONS,
    LIE_DETECTOR,
    REPORT_RESPONSE,
    ENABLE_REPORT,
    UPDATE_MOUNT,
    SHOW_QUEST_COMPLETION,
    SEND_TITLE_BOX,
    USE_SKILL_BOOK,
    SP_RESET,
    AP_RESET,
    POTION_POT_MSG,
    POTION_POT_UPDATE,
    FINISH_SORT,
    FINISH_GATHER,
    REPORT_RESULT,
    TRADE_LIMIT,
    UPDATE_GENDER,
    CHAR_INFO,
    PARTY_OPERATION,
    MEMBER_SEARCH,
    PARTY_SEARCH,
    BOOK_INFO,
    BUDDYLIST,
    GUILD_OPERATION,
    GUILD_SEARCH,
    ALLIANCE_OPERATION,
    SPAWN_PORTAL,
    MECH_PORTAL,
    SERVERMESSAGE,
    PIGMI_REWARD,
    OPEN_MAP,
    OWL_OF_MINERVA,
    OWL_RESULT,
    ENGAGE_REQUEST,
    ENGAGE_RESULT,
    YELLOW_CHAT,
    SHOP_DISCOUNT,
    CATCH_MOB,
    PET_PICKUP_MSG,
    PET_AUTO_EAT_MSG,
    SYNTHESIZING_MSG,
    FISHING_BOARD_UPDATE,
    BBS_OPERATION,
    NPC_HIDE,
    PLAYER_NPC,
    ENERGY,
    GHOST_POINT,
    GHOST_STATUS,
    FAIRY_PEND_MSG,
    SEND_PEDIGREE,
    OPEN_FAMILY,
    FAMILY_MESSAGE,
    FAMILY_INVITE,
    FAMILY_JUNIOR,
    SENIOR_MESSAGE,
    FAMILY,
    REP_INCREASE,
    FAMILY_LOGGEDIN,
    FAMILY_BUFF,
    FAMILY_USE_REQUEST,
    LEVEL_UPDATE,
    MARRIAGE_UPDATE,
    JOB_UPDATE,
    PENDANT_SLOT,
    FOLLOW_REQUEST,
    TOP_MSG,
    MID_MSG,
    CLEAR_MID_MSG,
    MAPLE_ADMIN,
    GM_POLICE,
    UPDATE_JAGUAR,
    ULTIMATE_EXPLORER,
    PAM_SONG,
    PROFESSION_INFO,
    UPDATE_IMP_TIME,
    ITEM_POT,
    UNK0092,
    GIVE_CHARACTER_SKILL,
    MULUNG_DOJO_RANKING,
    EQUIPPED_SKILL,
    TV_MESSAGE,
    UPDATE_INNER_SKILL,
    UPDATE_INNER_STATS,
    CONFIRM_CROSS_HUNTER,
    LOVE_OPERATION,
    CANCEL_TITLE_EFFECT,
    UPDATE_CORE_AURA,
    OPEN_WEB,
    CHAR_CASH,
    UNK00A6,
    SHOW_PREDICT_CARD,
    SYSTEM_PROCESS_LIST,
    AVATAR_MEGA_RESULT,
    AVATAR_MEGA,
    AVATAR_MEGA_REMOVE,
    FISHING_STORE,
    SHOW_PLAYER_CASH,
    PLAYER_CASH_UPDATE,
    WARP_TO_MAP,
    MTS_OPEN,
    CS_CHAR,
    CS_OPEN,
    LOGIN_WELCOME,
    RESET_SCREEN,
    MAP_BLOCKED,
    SERVER_BLOCKED,
    PARTY_BLOCKED,
    SHOW_EQUIP_EFFECT,
    MULTICHAT,
    WHISPER,
    BOSS_ENV,
    MOVE_ENV,
    UPDATE_ENV,
    UNK00BC,
    MAP_EFFECT,
    UNK00BF,
    CASH_SONG,
    GM_EFFECT,
    OX_QUIZ,
    GMEVENT_INSTRUCTIONS,
    CLOCK,
    BOAT_EFF,
    BOAT_EFFECT,
    LOGIN_SUCC,
    STOP_CLOCK,
    PYRAMID_UPDATE,
    PYRAMID_RESULT,
    QUICK_SLOT,
    MOVE_PLATFORM,
    PVP_INFO,
    DIRECTION_STATUS,
    GAIN_FORCE,
    QUICK_MOVE,
    SPAWN_PLAYER,
    REMOVE_PLAYER_FROM_MAP,
    CHATTEXT,
    CHALKBOARD,
    UPDATE_CHAR_BOX,
    SHOW_CONSUME_EFFECT,
    SHOW_SCROLL_EFFECT,
    SHOW_MAGNIFYING_EFFECT,
    SHOW_POTENTIAL_RESET,
    SHOW_ADDITIONAL_EFFECT,
    SHOW_ADDITIONAL_RESET,
    SHOW_FIREWORKS_EFFECT,
    SHOW_FUSION_EFFECT,
    PLAYER_DAMAGED,
    PVP_ATTACK,
    PVP_MIST,
    PVP_COOL,
    TESLA_TRIANGLE,
    FISHING_CAUGHT,
    PAMS_SONG,
    FOLLOW_EFFECT,
    CRAFT_EFFECT,
    CRAFT_COMPLETE,
    HARVESTED,
    SPAWN_PET,
    MOVE_PET,
    PET_CHAT,
    PET_NAMECHANGE,
    PET_EXCEPTION_LIST,
    SHOW_PET,
    PET_COMMAND,
    DRAGON_SPAWN,
    DRAGON_MOVE,
    DRAGON_REMOVE,
    ANDROID_SPAWN,
    ANDROID_MOVE,
    ANDROID_EMOTION,
    ANDROID_UPDATE,
    ANDROID_DEACTIVATED,
    MOVE_PLAYER,
    CLOSE_RANGE_ATTACK,
    RANGED_ATTACK,
    MAGIC_ATTACK,
    PASSIVE_ATTACK,
    SKILL_EFFECT,
    CANCEL_SKILL_EFFECT,
    DAMAGE_PLAYER,
    FACIAL_EXPRESSION,
    SHOW_ITEM_EFFECT,
    SHOW_TITLE_EFFECT,
    SHOW_UNK_EFFECT,
    SHOW_CHAIR,
    UPDATE_CHAR_LOOK,
    SHOW_FOREIGN_EFFECT,
    GIVE_FOREIGN_BUFF,
    CANCEL_FOREIGN_BUFF,
    UPDATE_PARTYMEMBER_HP,
    LOAD_GUILD_NAME,
    LOAD_GUILD_ICON,
    LOAD_TEAM,
    SHOW_HARVEST,
    PVP_HP,
    SHOW_DRAGON_FLY,
    UPDATE_ZERO_LOOK,
    REMOVE_ZERO_FROM_MAP,
    SHOW_SPECIAL_ATTACK,
    CANCEL_CHAIR,
    SHOW_SPECIAL_EFFECT,
    CURRENT_MAP_WARP,
    MESOBAG_SUCCESS,
    MESOBAG_FAILURE,
    UPDATE_QUEST_INFO,
    BUFF_BAR,
    PET_FLAG_CHANGE,
    PLAYER_HINT,
    EVENT_WINDOW,
    OPEN_UI_OPTION,
    INTRO_LOCK,
    INTRO_ENABLE_UI,
    INTRO_DISABLE_UI,
    SUMMON_HINT,
    SUMMON_HINT_MSG,
    ARAN_COMBO,
    ARAN_COMBO_RECHARGE,
    GAME_POLL_REPLY,
    CRAFT_MESSAGE,
    SPOUSE_MESSAGE,
    FOLLOW_MOVE,
    FOLLOW_MSG,
    GAME_POLL_QUESTION,
    CREATE_ULTIMATE,
    HARVEST_MESSAGE,
    SHOW_MAP_NAME,
    OPEN_BAG,
    DRAGON_BLINK,
    PVP_ICEGAGE,
    DIRECTION_INFO,
    REISSUE_MEDAL,
    PLAY_MOVIE,
    SHOW_CARTE,
    LUMINOUS_COMBO,
    UNKNOWN_1FC,
    COOLDOWN,
    SPAWN_SUMMON,
    REMOVE_SUMMON,
    MOVE_SUMMON,
    SUMMON_ATTACK,
    PVP_SUMMON,
    SUMMON_SKILL,
    DAMAGE_SUMMON,
    SPAWN_MONSTER,
    KILL_MONSTER,
    SPAWN_MONSTER_CONTROL,
    MOVE_MONSTER,
    MOVE_MONSTER_RESPONSE,
    DAMAGE_MONSTER,
    APPLY_MONSTER_STATUS,
    CANCEL_MONSTER_STATUS,
    UNK0185,
    SHOW_MONSTER_HP,
    SHOW_MAGNET,
    CATCH_MONSTER,
    MONSTER_PROPERTIES,
    REMOVE_TALK_MONSTER,
    TALK_MONSTER,
    SPAWN_NPC,
    REMOVE_NPC,
    SPAWN_NPC_REQUEST_CONTROLLER,
    NPC_ACTION,
    NPC_SET_SPECIAL_ACTION,
    NPC_SCRIPTABLE,
    UNK01A2,
    SPAWN_HIRED_MERCHANT,
    DESTROY_HIRED_MERCHANT,
    UPDATE_HIRED_MERCHANT,
    CHANGE_HIRED_MERCHANT_NAME,
    DROP_ITEM_FROM_MAPOBJECT,
    REMOVE_ITEM_FROM_MAP,
    SPAWN_LOVE,
    REMOVE_LOVE,
    SPAWN_DEFENDER,
    REMOVE_DEFENDER,
    SPAWN_DOOR,
    REMOVE_DOOR,
    MECH_DOOR_SPAWN,
    MECH_DOOR_REMOVE,
    REACTOR_HIT,
    REACTOR_SPAWN,
    REACTOR_DESTROY,
    SPAWN_EXTRACTOR,
    REMOVE_EXTRACTOR,
    ROLL_SNOWBALL,
    HIT_SNOWBALL,
    SNOWBALL_MESSAGE,
    LEFT_KNOCK_BACK,
    HIT_COCONUT,
    COCONUT_SCORE,
    MONSTER_CARNIVAL_START,
    MONSTER_CARNIVAL_OBTAINED_CP,
    MONSTER_CARNIVAL_PARTY_CP,
    MONSTER_CARNIVAL_SUMMON,
    MONSTER_CARNIVAL_DIED,
    CHAOS_ZAKUM_SHRINE,
    CHAOS_HORNTAIL_SHRINE,
    HORNTAIL_SHRINE,
    ENGLISH_QUIZ,
    PVP_TYPE,
    PVP_TRANSFORM,
    PVP_ENABLED,
    PVP_SCORE,
    PVP_RESULT,
    PVP_TEAM,
    PVP_SCOREBOARD,
    PVP_POINTS,
    PVP_KILLED,
    PVP_MODE,
    PVP_ICEKNIGHT,
    CAPTURE_FLAGS,
    CAPTURE_POSITION,
    CAPTURE_RESET,
    NPC_TALK,
    OPEN_NPC_SHOP,
    CONFIRM_SHOP_TRANSACTION,
    STORAGE_OPEN,
    STORAGE_OPERATION,
    MERCH_ITEM_MSG,
    MERCH_ITEM_STORE,
    RPS_GAME,
    MESSENGER,
    PLAYER_INTERACTION,
    DUEY,
    CS_UPDATE,
    CS_OPERATION,
    CS_UPDATE_MESO,
    CS_UNK1,
    CS_HOT,
    CS_DAILY,
    CS_UNK2,
    CS_GM_GIFI,
    CS_MSG,
    XMAS_SURPRISE,
    KEYMAP,
    PET_AUTO_HP,
    PET_AUTO_MP,
    PET_AUTO_BUFF,
    START_TV,
    REMOVE_TV,
    ENABLE_TV,
    SHOW_SCROLL_TIP,
    GET_MTS_TOKENS,
    MTS_OPERATION,
    VICIOUS_HAMMER,
    MACROSS_TICKET,
    ERRORR_MACROSS_TICKET,
    ALIEN_SOCKET_CREATOR,
    ECHO_MESSAGE,
    SHOW_MESO_GAIN,
    ANNOUNCE_PLAYER_SHOP,
    EARN_TITLE_MSG,
    ARIANT_PQ_START,
    ARIANT_SCOREBOARD,
    GET_CARD,
    CARD_SET,
    BOOK_STATS,
    R_MESOBAG_SUCCESS,
    R_MESOBAG_FAILURE,
    SPOUSE_CHAT,
    CHANGE_BACKGROUND,
    VISITOR,
    REGISTER_FAMILIAR,
    SPAWN_FAMILIAR,
    MOVE_FAMILIAR,
    ATTACK_FAMILIAR,
    UPDATE_FAMILIAR,
    TOUCH_FAMILIAR,
    SIDEKICK_OPERATION,
    RESET_MINIMAP,
    ACHIEVEMENT_RATIO,
    BOOSTER_FAMILIAR,
    BOOSTER_PACK,
    FAMILIAR_INFO,
    MONSTER_CARNIVAL_LEAVE,
    MONSTER_CARNIVAL_STATS,
    MONSTER_CARNIVAL_RESULT,
    MONSTER_CARNIVAL_RANKING,
    MOB_TO_MOB_DAMAGE,
    SKILL_EFFECT_MOB,
    ITEM_EFFECT_MOB,
    CYGNUS_ATTACK,
    SPECIAL_CREATION,
    EXIT_GAME,
    SPAWN_RUNE,
    MAP_SCENE,
    ELITE_BOSS_MSG,
    BOSS_PARTY_SEARCH_RESPONSE,
    BOSS_PARTY_SEARCH,
    SPAWN_ARROWS_TURRET,
    ARROWS_TURRET_ACTION,
    ARROWS_TURRET_ATTACK,
    CANCEL_ARROWS_TURRET,
    MONSTER_RESIST,
    SHOW_VOID_PRESSURE,
    SHOW_SUPER_SPECTRA,
    NPC_UPDATE_LIMITED_INFO,
    DIRECTION_FACIAL_EXPRESSION,
    LUCKY_MONEY,
    ADVANCED_ATTACK,
    ANGEL_REBORN_DONE,
    ANGEL_REBORN,
    HS_CHECK,//HS检测
    UPDATE_MAC_SKILL,
    FIRE_STEP,
    CONVEY_TO,
    REMOVE_RUNE,
    RUNE_OPERATION,
    RUNE_SKILL,
    TOP_MSG_WHITE,
    ELAB_OPERATION,
    OPEN_UI,
    FULLSCREEN_BLESS,
    ;

    private byte code = -2;
    public static boolean record = false;

    @Override
    public void setValue(byte code) {
        this.code = code;
    }

    @Override
    public byte getValue() {
        if (ServerProperties.ShowPacket()) {
            if (isRecordHeader(this)) {
                record = true;
                FileoutputUtil.log(FileoutputUtil.Packet_Record, "[服务端发送] " + name() + "  [0x" + code + "]  " + FileoutputUtil.CurrentReadable_Time() + "\r\n");
            } else {
                record = false;
            }
        }
        return this.code;
    }

    public short getValue(boolean show) {
        return code;
    }

    public boolean isRecordHeader(SendPacketOpcode opcode) {
        switch (opcode) {
            case MOVE_MONSTER_RESPONSE:
//            case WARP_TO_MAP:
//            case GUILD_OPERATION:
//            case PARTY_OPERATION:
//            case GIVE_BUFF:
//            case SPAWN_PLAYER:
//                return true;
            default:
                return false;
        }
    }

    public static boolean isSpamHeader(SendPacketOpcode opcode) {
        switch (opcode) {
            case MOVE_MONSTER_RESPONSE:
            case SPAWN_MONSTER:
            case SPAWN_MONSTER_CONTROL:
            case NPC_ACTION:
                return true;
            default:
                return false;
        }
    }

    public static Properties getDefaultProperties() throws FileNotFoundException, IOException {
        Properties props = new Properties();
        try (FileInputStream fileInputStream = new FileInputStream("sendops.properties")) {
            props.load(new BufferedReader(new InputStreamReader(fileInputStream, EncodingDetect.getJavaEncode("sendops.properties"))));
        }
        return props;
    }

    public static void reloadValues() {
        try {
            if (ServerConstants.loadop) {
                Properties props = new Properties();
                props.load(SendPacketOpcode.class.getClassLoader().getResourceAsStream("sendops.ini"));
                ExternalCodeTableGetter.populateValues(props, values());
            } else {
                ExternalCodeTableGetter.populateValues(getDefaultProperties(), values());
            }
        } catch (IOException e) {
            throw new RuntimeException("加载 sendops.properties 文件出现错误", e);
        }
    }

    static {
        reloadValues();
    }
}
